AWS、NewSQLデータベース「Amazon Aurora PostgreSQL Limitless Database」を正式提供開始
昨年末に開催されたAWSの年次イベント「re:Invent 2023」で、AWSは「Amazon Aurora Limitless Database」を発表しました。このNewSQLデータベースは、PostgreSQL/MySQLインターフェースとの互換でありながら、シャーディングによる書き込み性能やストレージ上限も大幅に強化されています。長らくプレビュー状態でしたが、東京リージョンを含めPostgreSQL版が正式提供されました。
Aurora Limitless ではデータはシャーディングされ、ルーターが実データのメタデータ管理や分散トランザクション、データ集約などを担います。
※ 画像引用元 https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/limitless-architecture.html
Limitless Databaseのの裏では、PostgreSQLネイティブのforeign tableや foreign data wrapperといった機能のほか、Aurora専用のストレージ技術「Grover」、動的なリソーススケーリングを実現する「Caspian」、分散システムにおける高精度の時刻同期を提供する「Amazon Time Sync Service」といったAWS独自の技術が活躍しています。
Amazon Aurora Limitless Databaseそのものについては、AWSJ 星野さんによるAWS Summit Japan 2024での発表『Amazon Aurora Limitless Database内部アーキテクチャ詳解 〜 スケーラビリティと⾼可⽤性の秘密 〜』がわかりやすいです(GA版と一部仕様が変わっている点にご注意ください)
Aurora Limitlessのドキュメントも同時に公開されたため、最低限の動作確認をやってみました
やってみた
AWSコンソールからAurora Limitlessを起動する場合、Aurora (PostgreSQL Compatible)のフローに従い、Aurora Limitless向けの設定を追加で行えば使い始められます。
Aurora Limitless エンジンの選択
AWSコンソールのRDSメニューからStandard create→Aurora (PostgreSQL Compatible)を選択し、「Show only versions that support Aurora Limitless Database」のフィルターを有効にすると、Aurora Limitlessエンジン(Aurora PostgreSQL with Limitless Database (Compatible with PostgreSQL 16.4)
) が選択されます。
Aurora Limitless 固有の設定
Aurora Limitlessエンジンを選択すると、Aurora Limitless固有の選択項目が増えます
Aurora Limitless Database では、キャパシティ範囲と可用性のためのフェイルオーバー設定を行います。
キャパシティはAurora capacity units (ACU)で下限と上限を指定します。
また、各シャードのフェイルオーバー先のスタンバイ数を0~2の範囲で指定できます。スタンバイ機を増やすほど可用性も向上しますが、利用費にも跳ね返ります。
エンドポイントの確認
起動を行うと、2種類のロールのクラスターが起動します
- Limitless cluster
- DB shard group
Aurora Limitlessには5つのエンドポイントがあります
- クラスターエンドポイント
- リーダーエンドポイント
- カスタムエンドポイント
- インスタンスエンドポイント
- (NEW)Aurora Limitless Databaseのシャードエンドポイント
5つめの新しいエンドポイントは DB shard groupロールのデータベースのConfigurationタブから確認できます。
AWS APIからもこのシャードグループを確認できます。
$ aws rds describe-db-shard-groups
{
"DBShardGroups": [
{
"DBShardGroupResourceId": "shardgroup-58dd7a78ff2c4fb88b27faf0da2dfac7",
"DBShardGroupIdentifier": "my-first-newsql-group",
"DBClusterIdentifier": "my-first-newsql",
"MaxACU": 32.0,
"MinACU": 16.0,
"ComputeRedundancy": 1,
"Status": "available",
"PubliclyAccessible": false,
"Endpoint": "my-first-newsql-group.shardgrp-xxx.ap-northeast-1.rds.amazonaws.com",
"DBShardGroupArn": "arn:aws:rds:ap-northeast-1:12345:shard-group:shardgroup-58dd7a78ff2c4fb88b27faf0da2dfac7",
"TagList": []
}
]
}
$ aws rds describe-db-shard-groups --db-shard-group-identifier my-first-newsql-group
{
"DBShardGroups": [
{
"DBShardGroupResourceId": "shardgroup-58dd7a78ff2c4fb88b27faf0da2dfac7",
"DBShardGroupIdentifier": "my-first-newsql-group",
"DBClusterIdentifier": "my-first-newsql",
"MaxACU": 32.0,
"MinACU": 16.0,
"ComputeRedundancy": 1,
"Status": "available",
"PubliclyAccessible": false,
"Endpoint": "my-first-newsql-group.shardgrp-xxx.ap-northeast-1.rds.amazonaws.com",
"DBShardGroupArn": "arn:aws:rds:ap-northeast-1:12345:shard-group:shardgroup-58dd7a78ff2c4fb88b27faf0da2dfac7",
"TagList": []
}
]
}
接続
接続時には以下の2点に気をつけてください
- ポートが
5431
(PostgreSQLデフォルトは 5432) - データベース名が
postgres_limitless
シャードグループエンドポイントに接続してみましょう
$ HOST=my-first-newsql-group.shardgrp-xxx.ap-northeast-1.rds.amazonaws.com
$ psql -h $HOST -p 5431 -U postgres -d postgres_limitless
Password for user postgres:
psql (16.4 (Ubuntu 16.4-0ubuntu0.24.04.2))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
postgres_limitless=> select version();
version
-------------------------------------------------------------------------------------------------------------
PostgreSQL 16.4 on aarch64-unknown-linux-gnu, compiled by aarch64-unknown-linux-gnu-gcc (GCC) 9.5.0, 64-bit
(1 row)
データベース名(postgres_limitless
)を指定しない場合、以下の様なエラーが発生します
$ psql -h $HOST -p 5431 -U postgres
Password for user postgres:
psql: error: connection to server at "my-first-newsql-group.shardgrp-xxx.ap-northeast-1.rds.amazonaws.com" (172.31.12.207), port 5431 failed: FATAL: invalid connection request to non-limitless database "postgres" by user "postgres".
DETAIL: Only connections to limitless databases is allowed.
テーブル作成してみる
Limitless には以下の固有のテーブルが存在します
- シャードキーを元にデータをシャーディングするsharded テーブル
- 各シャードにデータを格納するreference テーブル(マスタデータなどを想定)
- デフォルトのどこかにシャードに格納されるstandard テーブル
Redshiftのdistribution keyと同様に、シャード間通信が発生しないようにうまくテーブル設計することで、スケールしやすくなります。
作成したレコードに対して、シャードキーの変更はできず(例えば、キーのUPDATEによるリシャード)、レコードの削除&再挿入が必要です。
それぞれを作ってみましょう
-- sharded table
SET rds_aurora.limitless_create_table_mode='sharded';
SET rds_aurora.limitless_create_table_shard_key='{"item_id", "item_cat"}';
CREATE TABLE items(item_id int, item_cat varchar, val int, item text);
SET rds_aurora.limitless_create_table_collocate_with='items';
CREATE TABLE item_description(item_id int, item_cat varchar, color_id int);
-- reference table
SET rds_aurora.limitless_create_table_mode='reference';
CREATE TABLE colors(color_id int primary key, color varchar);
データを投入し、SELECT結果と実行計画を確認します
postgres_limitless=> select c.* from item_description AS i_d JOIN colors AS c ON i_d.color_id = c.color_id;
color_id | color
----------+-------
1 | blue
(1 row)
postgres_limitless=> explain select c.* from item_description AS i_d JOIN colors AS c ON i_d.color_id = c.color_id;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Merge Join (cost=3826.67..4432.39 rows=39926 width=36)
Merge Cond: (c.color_id = i_d.color_id)
-> Sort (cost=754.38..757.79 rows=1365 width=36)
Sort Key: c.color_id
-> Foreign Scan on colors c (cost=100.00..683.30 rows=1365 width=36)
-> Sort (cost=3072.29..3086.92 rows=5850 width=4)
Sort Key: i_d.color_id
-> Append (cost=100.00..2706.25 rows=5850 width=4)
-> Async Foreign Scan on item_description_fs00001 i_d_1 (cost=100.00..1338.50 rows=2925 width=4)
-> Async Foreign Scan on item_description_fs00002 i_d_2 (cost=100.00..1338.50 rows=2925 width=4)
(10 rows)
EXPLAINには Aurora Limitless 用の rds_aurora.limitless_explain_options
オプションが存在し、ルーターとシャードレベルでの実行計画を確認できます。Limitlessのルーターはデータシャーディング用のルーティング以外にも、クエリーエンジン的な機能も持ち合わせています。
ルーターとシャードを確認
rds_aurora.limitless_subclusters
からルーター・シャード情報を確認できます。
postgres_limitless=> SELECT * FROM rds_aurora.limitless_subclusters order by subcluster_id;
subcluster_id | subcluster_type
---------------+-----------------
2 | router
3 | router
4 | shard
5 | shard
(4 rows)
費用
Limitless Databaseのはr6g.largeのようなインスタンスタイプではなく、Aurora Serverless v2と同じくAurora Capacity Unit(ACU)を指定しています。また、I/O Optimizedのみ選択可能です。
Limitless Databaseの ACU単価はServerless v2のI/O Optimizedと同じであり、例えば東京リージョンの場合、$0.26/ACU/Hourです。
制約
- ベースとなるPostgreSQLのエンジンバージョンは 16.4 のみ
- PostgreSQLのすべてのSQLに対応しているわけでは有りません。詳細はドキュメントをご確認ください (https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/limitless-reference.html)
- PostgreSQLのすべてのエクステンションに対応しているわけでは有りません。詳細はドキュメントをご確認ください(https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/limitless-reference.DDL-limitations.html#limitless-reference.DDL-limitations.Extensions)
- キャパシティ(ACU)は16から6144の範囲で指定可能です。上限の6144はソフトリミットです
- トランザクションはPostgreSQLのRead CommittedとRead UncommittedとRepeatable Readに対応し、serializableには対応しています。
最後に
AWSのNewSQLサービス Limitless Databaseのがついに正式提供開始しました。
RDBでは解決の難しい書き込み性能がシャーディングで解決されており、水平・垂直にスケールし、PostgreSQL互換のインターフェースです。
Amazon Aurora PostgreSQL Limitless Databaseは分散データベースの難しいところの多くが隠蔽され、RDBのような感覚で単一エンドポイントにSQLを投げるだけでが使えるよう提供されており、評価・導入しやすいのではないでしょうか。
AuroraのWriteのスケーラビリティやストレージサイズに課題がある場合、ぜひご検討ください。